#ifndef IMAGECANVAS_H
#define IMAGECANVAS_H

#include <QDeclarativeItem>
#include <QPainter>

class CanvasPoint
{
public:
    CanvasPoint(){}

    QPen    pen;
    QPointF start;
    QPointF end;
    int     type;
};

class ImageCanvas : public QDeclarativeItem
{
    Q_OBJECT
    Q_ENUMS(CanvasError)
    Q_ENUMS(DrawType)
    Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor NOTIFY penColorChanged)
    Q_PROPERTY(int penWidth READ penWidth WRITE setPenWidth NOTIFY penWidthChanged)
    Q_PROPERTY(int penX READ penX WRITE setPenX NOTIFY penXChanged)
    Q_PROPERTY(int penY READ penY WRITE setPenY NOTIFY penYChanged)
    Q_PROPERTY(QUrl underneathImage READ underneathImage WRITE setUnderneathImage NOTIFY underneathImageChanged)
    Q_PROPERTY(bool penEnabled READ penEnabled WRITE setPenEnabled NOTIFY penEnabledChanged)
    Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize NOTIFY sourceSizeChanged)
    Q_PROPERTY(QSize originalSourceSize READ originalSourceSize WRITE setOriginalSourceSize NOTIFY originalSourceSizeChanged)
    Q_PROPERTY(Qt::TransformationMode transformationMode READ transformationMode WRITE setTransformationMode NOTIFY transformationModeChanged)
    Q_PROPERTY(Qt::AspectRatioMode aspectRatio READ aspectRatio WRITE setAspectRatio NOTIFY aspectRatioChanged)
    Q_PROPERTY(CanvasError error READ error NOTIFY errorChanged)
    Q_PROPERTY(QPoint penPosition READ penPosition WRITE setPenPosition NOTIFY penPositionChanged)
    Q_PROPERTY(Qt::PenCapStyle penCapStyle READ penCapStyle WRITE setPenCapStyle NOTIFY penCapStyleChanged)
    Q_PROPERTY(Qt::PenJoinStyle penJoinStyle READ penJoinStyle WRITE setPenJoinStyle NOTIFY penJoinStyleChanged)
    Q_PROPERTY(DrawType drawType READ drawType WRITE setDrawType NOTIFY drawTypeChanged)

public:
    enum CanvasError{
        NoError = 0,
        LoadError,
        SaveError,
        CreateError
    };

    enum DrawType{
        NoDraw,
        DrawPen,
        DrawLine
    };

    explicit ImageCanvas(QDeclarativeItem *parent = 0);

    Q_INVOKABLE void createEmpty(int width,int height);
    Q_INVOKABLE void save(QString filename);
    Q_INVOKABLE void undo();
    Q_INVOKABLE QString freeFilename();

protected:
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* styleOption, QWidget* widget);

private:
    QColor penColor(){return m_color;}
    void setPenColor(QColor color){m_color = color;emit penColorChanged();}

    int penWidth(){return m_penWidth;}
    void setPenWidth(int penWidth){m_penWidth = penWidth; emit penWidthChanged();}

    int penX(){return m_penX;}
    int penY(){return m_penY;}
    void setPenX(int penX){m_penX=penX; emit penXChanged();updateImage();}
    void setPenY(int penY){m_penY=penY; emit penYChanged();updateImage();}
    QUrl underneathImage(){return m_underneathImageFilename;}
    void setUnderneathImage(QUrl filename);
    bool penEnabled(){return m_penEnabled;}
    void setPenEnabled(bool enabled){m_penEnabled=enabled;emit penEnabledChanged();}
    QSize sourceSize(){return m_sourceSize;}
    void setSourceSize(QSize size);
    Qt::TransformationMode transformationMode(){return m_transformMode;}
    void setTransformationMode(Qt::TransformationMode mode){m_transformMode=mode;emit transformationModeChanged();}
    Qt::AspectRatioMode aspectRatio(){return m_aspect;}
    void setAspectRatio(Qt::AspectRatioMode mode){m_aspect=mode;emit aspectRatioChanged();}
    void updateImage();
    CanvasError error(){return m_error;}
    QSize originalSourceSize(){return m_originalSourceSize;}
    void setOriginalSourceSize(QSize size){m_originalSourceSize=size;emit originalSourceSizeChanged();}
    QPoint penPosition(){return QPoint(m_penX,m_penY);}
    void setPenPosition(QPoint point){m_penX=point.x();m_penY=point.y(); emit penPositionChanged(); updateImage();}
    Qt::PenCapStyle penCapStyle(){return m_penCapStyle;}
    void setPenCapStyle(Qt::PenCapStyle style){m_penCapStyle=style;emit penCapStyleChanged();}
    Qt::PenJoinStyle penJoinStyle(){return m_penJoinStyle;}
    void setPenJoinStyle(Qt::PenJoinStyle style){m_penJoinStyle=style;emit penJoinStyleChanged();}
    DrawType drawType(){return m_drawType;}
    void setDrawType(DrawType type){m_drawType=type;emit drawTypeChanged();}

signals:
    void penColorChanged();
    void penWidthChanged();
    void penXChanged();
    void penYChanged();
    void underneathImageChanged();
    void updated();
    void errorChanged();
    void penEnabledChanged();
    void sourceSizeChanged();
    void transformationModeChanged();
    void aspectRatioChanged();
    void saveChanged();
    void originalSourceSizeChanged();
    void penPositionChanged();
    void penCapStyleChanged();
    void penJoinStyleChanged();
    void drawTypeChanged();

private:
    QColor  m_color;
    int     m_penWidth;
    int     m_penX;
    int     m_penY;
    QList< CanvasPoint > m_penPoints;
    QList< CanvasPoint > m_penPointsScreen;
    QUrl    m_underneathImageFilename;
    QImage  m_sourceImage;
    QPixmap m_editImage;

    CanvasError m_error;
    QString m_errorString;
    bool    m_penEnabled;
    QSize   m_sourceSize;
    QSize   m_originalSourceSize;
    Qt::AspectRatioMode m_aspect;
    Qt::TransformationMode m_transformMode;
    bool    m_saveInProgress;
    Qt::PenCapStyle m_penCapStyle;
    Qt::PenJoinStyle m_penJoinStyle;
    DrawType    m_drawType;
};

QML_DECLARE_TYPE(ImageCanvas)

#endif // IMAGECANVAS_H
